/**
 * Copyright 2011 AJG van Schie
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.googlecode.julius.controller;

import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.ResourceBundle;

import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.chart.AreaChart;
import javafx.scene.chart.Axis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.ProgressBar;

import org.apache.log4j.Logger;

import com.googlecode.julius.controller.ControllerApi.DayEntry;
import com.googlecode.julius.controller.ControllerApi.Sprint;
import com.googlecode.julius.data.ReaderApiImpl;
import com.googlecode.julius.data.define.Define4Reader;
import com.googlecode.julius.gui.BurnDownChart;
import com.googlecode.julius.utils.ParallelForEach.ProgressCallback;

public class GraphController implements Initializable {

    private static Logger log = Logger.getLogger(GraphController.class);

    private BurnDownChart burnchart;
    private ControllerImpl controller;

    @FXML
    // let op items should be linked on fx:id not id
    private AreaChart<String, Number> areaChart;

    @FXML
    private Axis<String> xAxis;

    @FXML
    private NumberAxis yAxis;

    @FXML
    private ProgressBar downloadBar;

    @FXML
    private ChoiceBox<Sprint> comboMilestone;

    public void readStoryInfo() {
        log.info("read story event");

        final Sprint sprint = comboMilestone.getValue();

        Task<Void> task = new Task<Void>() {

            private Collection<DayEntry> dayEntries;

            private final ProgressCallback callback = new ProgressCallback() {
                @Override
                public void progress(final int part, final int total) {
                    Platform.runLater(new Runnable() {
                        @Override
                        public void run() {
                            updateProgress(part, total);
                        }
                    });
                }
            };

            @Override
            protected Void call() throws Exception {
                try {
                    dayEntries = controller.readData(sprint, callback);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        burnchart.render(sprint, dayEntries);
                    }
                });
                return null;
            }

        };
        downloadBar.progressProperty().bind(task.progressProperty());
        new Thread(task).start();

    }

    public void printChart() {
        burnchart.print();
    }

    @Override
    public void initialize(final URL arg0, final ResourceBundle arg1) {
        String user = System.getProperty("define.user");
        String pass = System.getProperty("define.pass");

        try {
            Define4Reader reader = new Define4Reader(user, pass);

            controller = new ControllerImpl(new ReaderApiImpl(reader));

            burnchart = new BurnDownChart(areaChart, xAxis, yAxis);

            initSprintComboBox(controller);

        } catch (Exception e) {
            // TODO show msg box about credentials
            log.error("error", e);
        }
    }

    private void initSprintComboBox(final ControllerImpl controller) {
        List<Sprint> sortedSprints = controller.readSprints();
        Collections.sort(sortedSprints, new Comparator<Sprint>() {
            @Override
            public int compare(final Sprint o1, final Sprint o2) {
                return o1.name().compareTo(o2.name());
            }
        });

        comboMilestone.itemsProperty().get().clear();
        for (Sprint milestone : sortedSprints) {
            comboMilestone.itemsProperty().get().add(milestone);
        }
    }

}
